jetcrab\parser\statements/
variable.rs

1use crate::ast::{Node, VariableDeclaration, VariableDeclarator};
2use crate::lexer::TokenKind;
3use crate::parser::error::ParseResult;
4use crate::parser::Parser;
5
6impl Parser {
7    pub fn parse_variable_declaration(&mut self) -> ParseResult<Node> {
8        let kind = if let Some(token) = &self.current {
9            if let TokenKind::Keyword(kw) = &token.kind {
10                match kw.as_str() {
11                    "let" => "let",
12                    "const" => "const",
13                    "var" => "var",
14                    _ => unreachable!(),
15                }
16            } else {
17                unreachable!()
18            }
19        } else {
20            unreachable!()
21        };
22
23        self.advance();
24
25        let mut declarations = Vec::new();
26
27        loop {
28            let id = if self.check(TokenKind::LeftBrace) || self.check(TokenKind::LeftBracket) {
29                self.parse_destructuring_pattern()?
30            } else {
31                self.parse_identifier()?
32            };
33            let init = if self.check(TokenKind::Assign) {
34                self.advance();
35                Some(Box::new(self.parse_expression()?))
36            } else {
37                None
38            };
39
40            let span = self.create_span_from_tokens();
41            declarations.push(VariableDeclarator {
42                id: Box::new(id),
43                init,
44                span: Some(span),
45            });
46
47            if !self.check(TokenKind::Comma) {
48                break;
49            }
50            self.advance();
51        }
52
53        if self.check(TokenKind::Semicolon) {
54            self.advance();
55        }
56
57        let span = self.create_span_from_tokens();
58        Ok(Node::VariableDeclaration(VariableDeclaration {
59            kind: kind.to_string(),
60            declarations,
61            span: Some(span),
62        }))
63    }
64
65    pub fn parse_variable_declaration_without_semicolon(&mut self) -> ParseResult<Node> {
66        let kind = if let Some(token) = &self.current {
67            if let TokenKind::Keyword(kw) = &token.kind {
68                match kw.as_str() {
69                    "let" => "let",
70                    "const" => "const",
71                    "var" => "var",
72                    _ => unreachable!(),
73                }
74            } else {
75                unreachable!()
76            }
77        } else {
78            unreachable!()
79        };
80
81        self.advance();
82
83        let mut declarations = Vec::new();
84
85        loop {
86            let id = if self.check(TokenKind::LeftBrace) || self.check(TokenKind::LeftBracket) {
87                self.parse_destructuring_pattern()?
88            } else {
89                self.parse_identifier()?
90            };
91            let init = if self.check(TokenKind::Assign) {
92                self.advance();
93                Some(Box::new(self.parse_expression()?))
94            } else {
95                None
96            };
97
98            let span = self.create_span_from_tokens();
99            declarations.push(VariableDeclarator {
100                id: Box::new(id),
101                init,
102                span: Some(span),
103            });
104
105            if !self.check(TokenKind::Comma) {
106                break;
107            }
108            self.advance();
109        }
110
111        let span = self.create_span_from_tokens();
112        Ok(Node::VariableDeclaration(VariableDeclaration {
113            kind: kind.to_string(),
114            declarations,
115            span: Some(span),
116        }))
117    }
118}